//package org.gl.rtsp;
//
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.io.InputStreamReader;
//import java.io.OutputStream;
//import java.net.InetAddress;
//import java.net.ServerSocket;
//import java.net.Socket;
//import java.net.SocketException;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//
//import org.gl.java.Log;
//
//
//public class RTSPServer {
//	private static int seq = 1;
//	private static final int PROXY_PORT = 5540;
//	private static final String CRLF = "\r\n";
//	private static final String URL = "rtsp://192.168.4.45:"+PROXY_PORT+"/proxy?url=rtsp://192.168.2.64:5540/";
//	public static final String TAG = "RTSPSERVER";
//	
//
//	/**
//	 * @param args
//	 * @throws IOException
//	 */
//	public static void main(String[] args) throws IOException {
//		RTSPServer t = new RTSPServer();
//		t.start();
//	}
//
//	private void start() throws IOException {
//		// TODO 自动生成方法存根
//		String mes = "";
//		ServerSocket serversocket = new ServerSocket(PROXY_PORT);
//		while (true) {
//			new WorkerThread(serversocket.accept());
//			
//		}
//	}
//	// One thread per client
//		class WorkerThread extends Thread implements Runnable {
//
//			private final Socket mClient;
//			private final OutputStream mOutput;
//			private final BufferedReader mInput;
//
//			// Each client has an associated session
//
//			public WorkerThread(final Socket client) throws IOException {
//				mInput = new BufferedReader(new InputStreamReader(client.getInputStream()));
//				mOutput = client.getOutputStream();
//				mClient = client;
//			}
//
//			public void run() {
//				Request request;
//				Response response  = new Response(mOutput); ;
//
//				Log.i(TAG, "Connection from "+mClient.getInetAddress().getHostAddress());
//
//				while (!Thread.interrupted()) {
//
//					request = null;
//					response = null;
//
//					// Parse the request
//					try {
//						request = Request.parseRequest(mInput);
//					} catch (SocketException e) {
//						// Client has left
//						break;
//					} catch (Exception e) {
//						// We don't understand the request :/
//						
//						response.status = StatusCode.STATUS_BAD_REQUEST;
//						response.returnErr(mOutput);
//					}
//
//					// Do something accordingly like starting the streams, sending a session description
//					if (request != null) {
//						try {
//							response = processRequest(request);
//						}
//						catch (Exception e) {
//							// This alerts the main thread that something has gone wrong in this thread
//							postError(e);
//							Log.e(TAG,e.getMessage()!=null?e.getMessage():"An error occurred");
//							e.printStackTrace();
//							response.returnErr(mOutput);
//						}
//					}
//
//					// We always send a response
//					// The client will receive an "INTERNAL SERVER ERROR" if an exception has been thrown at some point
//					try {
//						response.send(mOutput);
//					} catch (IOException e) {
//						Log.e(TAG,"Response was not sent properly");
//						break;
//					}
//
//				}
//
//				// Streaming stops when client disconnects
//				boolean streaming = response.isStreaming();
//				mSession.syncStop();
//				if (streaming && !isStreaming()) {
//					postMessage(MESSAGE_STREAMING_STOPPED);
//				}
//				mSession.release();
//
//				try {
//					mClient.close();
//				} catch (IOException ignore) {}
//
//				Log.i(TAG, "Client disconnected");
//
//			}
//
//			private void postError(Exception e) {
//				// TODO Auto-generated method stub
//				
//			}
//
//			public Response processRequest(Request request) throws IllegalStateException, IOException {
//				Response response = new Response(request);
//
//				/* ********************************************************************************** */
//				/* ********************************* Method DESCRIBE ******************************** */
//				/* ********************************************************************************** */
//				if (request.method.equalsIgnoreCase("DESCRIBE")) {
//
//					// Parse the requested URI and configure the session
//					mSession = handleRequest(request.uri, mClient);
//					mSessions.put(mSession, null);
//					mSession.syncConfigure();
//					
//					String requestContent = mSession.getSessionDescription();
//					String requestAttributes = 
//							"Content-Base: "+mClient.getLocalAddress().getHostAddress()+":"+mClient.getLocalPort()+"/\r\n" +
//									"Content-Type: application/sdp\r\n";
//
//					response.attributes = requestAttributes;
//					response.content = requestContent;
//
//					// If no exception has been thrown, we reply with OK
//					response.status = Response.STATUS_OK;
//
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************* Method OPTIONS ********************************* */
//				/* ********************************************************************************** */
//				else if (request.method.equalsIgnoreCase("OPTIONS")) {
//					response.status = Response.STATUS_OK;
//					response.attributes = "Public: DESCRIBE,SETUP,TEARDOWN,PLAY,PAUSE\r\n";
//					response.status = Response.STATUS_OK;
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************** Method SETUP ********************************** */
//				/* ********************************************************************************** */
//				else if (request.method.equalsIgnoreCase("SETUP")) {
//					Pattern p; Matcher m;
//					int p2, p1, ssrc, trackId, src[];
//					String destination;
//
//					p = Pattern.compile("trackID=(\\w+)",Pattern.CASE_INSENSITIVE);
//					m = p.matcher(request.uri);
//
//					if (!m.find()) {
//						response.status = Response.STATUS_BAD_REQUEST;
//						return response;
//					} 
//
//					trackId = Integer.parseInt(m.group(1));
//
//					if (!mSession.trackExists(trackId)) {
//						response.status = Response.STATUS_NOT_FOUND;
//						return response;
//					}
//
//					p = Pattern.compile("client_port=(\\d+)-(\\d+)",Pattern.CASE_INSENSITIVE);
//					m = p.matcher(request.headers.get("transport"));
//
//					if (!m.find()) {
//						int[] ports = mSession.getTrack(trackId).getDestinationPorts();
//						p1 = ports[0];
//						p2 = ports[1];
//					}
//					else {
//						p1 = Integer.parseInt(m.group(1)); 
//						p2 = Integer.parseInt(m.group(2));
//					}
//
//					ssrc = mSession.getTrack(trackId).getSSRC();
//					src = mSession.getTrack(trackId).getLocalPorts();
//					destination = mSession.getDestination();
//
//					mSession.getTrack(trackId).setDestinationPorts(p1, p2);
//					
//					boolean streaming = isStreaming();
//					mSession.syncStart(trackId);
//					if (!streaming && isStreaming()) {
//						postMessage(MESSAGE_STREAMING_STARTED);
//					}
//
//					response.attributes = "Transport: RTP/AVP/UDP;"+(InetAddress.getByName(destination).isMulticastAddress()?"multicast":"unicast")+
//							";destination="+mSession.getDestination()+
//							";client_port="+p1+"-"+p2+
//							";server_port="+src[0]+"-"+src[1]+
//							";ssrc="+Integer.toHexString(ssrc)+
//							";mode=play\r\n" +
//							"Session: "+ "1185d20035702ca" + "\r\n" +
//							"Cache-Control: no-cache\r\n";
//					response.status = Response.STATUS_OK;
//
//					// If no exception has been thrown, we reply with OK
//					response.status = Response.STATUS_OK;
//
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************** Method PLAY *********************************** */
//				/* ********************************************************************************** */
//				else if (request.method.equalsIgnoreCase("PLAY")) {
//					String requestAttributes = "RTP-Info: ";
//					if (mSession.trackExists(0)) requestAttributes += "url=rtsp://"+mClient.getLocalAddress().getHostAddress()+":"+mClient.getLocalPort()+"/trackID="+0+";seq=0,";
//					if (mSession.trackExists(1)) requestAttributes += "url=rtsp://"+mClient.getLocalAddress().getHostAddress()+":"+mClient.getLocalPort()+"/trackID="+1+";seq=0,";
//					requestAttributes = requestAttributes.substring(0, requestAttributes.length()-1) + "\r\nSession: 1185d20035702ca\r\n";
//
//					response.attributes = requestAttributes;
//
//					// If no exception has been thrown, we reply with OK
//					response.status = Response.STATUS_OK;
//
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************** Method PAUSE ********************************** */
//				/* ********************************************************************************** */
//				else if (request.method.equalsIgnoreCase("PAUSE")) {
//					response.status = Response.STATUS_OK;
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************* Method TEARDOWN ******************************** */
//				/* ********************************************************************************** */
//				else if (request.method.equalsIgnoreCase("TEARDOWN")) {
//					response.status = Response.STATUS_OK;
//				}
//
//				/* ********************************************************************************** */
//				/* ********************************* Unknown method ? ******************************* */
//				/* ********************************************************************************** */
//				else {
//					Log.e(TAG,"Command unknown: "+request);
//					response.status = Response.STATUS_BAD_REQUEST;
//				}
//
//				return response;
//
//			}
//
//		}
//}
